<template>
  <div>
        <!-- 面包屑 -->
        <el-breadcrumb separator-class="el-icon-arrow-right">
            <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>权限管理</el-breadcrumb-item>
            <el-breadcrumb-item>角色列表</el-breadcrumb-item>
        </el-breadcrumb>
        <!-- 卡片 -->
        <el-card>
            <!-- 添加角色按钮 -->
            <el-row>
                <el-col :span="6">
                    <el-button type="primary" @click="showAddRoles">添加角色</el-button>
                </el-col>
            </el-row>
            <!-- 数据列表 -->
            <el-table
            border
            scripe
            :data="rolesList"
            
            >
                <!-- 拓展列 -->
                <el-table-column type="expand">
                    <template slot-scope="scope">
                        <!-- 一级权限 -->
                        <el-row :class='["vcenter","bottomBorder",index === 0 ? "topBorder":""]'  v-for="(item,index) in scope.row.children" :key="item.id">
                            
                            <el-col :span="4">
                                <el-tag closable>{{item.authName}}</el-tag>
                                <i class="el-icon-caret-right"></i>
                                
                            </el-col>
                            <!-- 二级权限 -->
                            <el-col :span="20" >
                                <el-row :class="['vcenter',index1 === 0 ? '':'topBorder']"  v-for="(item1,index1) in item.children" :key="item1.id">
                                    <el-col :span="5">
                                        <el-tag type="success" closable>{{item1.authName}}</el-tag>                                      
                                        <i class="el-icon-caret-right"></i>
                                    </el-col> 
                                    <!-- 三级权限 -->
                                    <el-col :span="19" >   
                                        <el-tag type="warning" closable v-for="item2 in item1.children" :key="item2.id" @close="deleteTag(scope.row,item2.id)">{{item2.authName}}</el-tag>
                                    </el-col>
                         
                                    
                                </el-row>
                                
                            </el-col>
                          
                             
                        </el-row>
                        <!-- <pre>{{scope.row}}</pre> -->
                        <!-- <pre>{{scope.row.children}}</pre> -->
                        
                    </template>
                </el-table-column>
                <!-- 索引列 -->
                <el-table-column type="index" label="#"></el-table-column>
                <el-table-column label="角色名称" prop="roleName"></el-table-column>
                <el-table-column label="角色描述" prop="roleDesc"></el-table-column>
                <el-table-column label="操作" width='350'>
                    <template slot-scope="scope">
                        <!-- 操作按钮组件 -->
                        <el-button type="primary" icon="el-icon-edit" @click="showEditRoles(scope.row)">编辑</el-button>
                        <el-button type="danger" icon="el-icon-delete" @click="deleteRoles(scope.row)">删除</el-button>
                        <el-button type="warning" icon="el-icon-setting" @click="editRight(scope.row)">权限分配</el-button>
                    </template>
                </el-table-column>
            </el-table>
        </el-card>
        <!-- 点击权限编辑按钮，进行弹出框提示 -->
        <el-dialog
        title="编辑权限"
        :visible.sync="editDialogClosed"
        width="50%"
        @close="clearRight"
        >
            <!-- 弹出框属性结构 -->
            <el-tree ref="treeRef" node-key="id" :default-checked-keys="rightYesList" :data="rightList" :props="rightProps" show-checkbox default-expand-all></el-tree>
         
            <span slot="footer">
                <el-button @click="editDialogClosed = false">取 消</el-button>
                <el-button type="primary" @click="updateRights">确 定</el-button>
            </span>
        </el-dialog>
        <!-- 点击添加角色按钮，进行弹出框提示 -->
        <el-dialog
        title="提示"
        :visible.sync="addRolesVisible"
        width="50%"
        >
            <el-form ref="addRolesRef" :rules="addRolesRules" :model="addRolesForm" label-width="80px">
                <el-form-item label="角色名称" prop="roleName">
                    <el-input v-model="addRolesForm.roleName"></el-input>
                </el-form-item>
                <el-form-item label="角色描述" prop="roleDesc">
                    <el-input v-model="addRolesForm.roleDesc"></el-input>
                </el-form-item>
            </el-form>
            <span slot="footer" class="dialog-footer">
                <el-button @click="resetAddRolesFrom">取 消</el-button>
                <el-button type="primary" @click="submitAddRolesFrom">确 定</el-button>
            </span>
        </el-dialog>
        <!-- 点击编辑角色按钮，进行弹出窗提示 -->
        <el-dialog
        title="提示"
        :visible.sync="editRolesVisible"
        width="50%"
        >
            <el-form ref="editRolesRef" :rules="editRolesRules" :model="editRolesForm" label-width="80px">
                <el-form-item label="角色名称" prop="roleName">
                    <el-input v-model="editRolesForm.roleName"></el-input>
                </el-form-item>
                <el-form-item label="角色描述" prop="roleDesc">
                    <el-input v-model="editRolesForm.roleDesc"></el-input>
                </el-form-item>
            </el-form>
            <span slot="footer" class="dialog-footer">
                <el-button @click="resetEditRolesFrom">取 消</el-button>
                <el-button type="primary" @click="submitEditRolesFrom">确 定</el-button>
            </span>
        </el-dialog>
  </div>
</template>

<script>
    export default {
        // 数据
        data(){
            return{
                // 角色列表数据
                rolesList:[],
                // 正在使用的角色id
                roleId:"",
                // 点击编辑按钮时，是否要弹出框提示
                editDialogClosed:false,
                // 获取的权限列表数据
                rightList:[],
                // 获取的权限列表数据渲染时按照的属性
                rightProps:{
                    children:"children",
                    label:"authName"
                },
                // 要勾选的权限列表选项
                rightYesList:[],
                // 点击添加角色按钮，是否要弹出框提示
                addRolesVisible:false,
                // 要提交的角色表单
                addRolesForm:{
                    roleName:"",
                    roleDesc:""
                },
                // 添加角色的校验规则
                addRolesRules:{
                    // 角色名称校验规则
                    roleName: [
                        { required: true, message: '请输入角色名称', trigger: 'blur' },
                        { min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' }
                    ],
                    // 角色描述校验规则
                    roleDesc:[
                        { required: false, message: '请输入角色描述', trigger: 'blur' }
                    ]
                },
                // 点击编辑角色按钮，是否要弹出框提示
                editRolesVisible:false,
                // 要进行修改的角色表单
                editRolesForm:{ },
                // 编辑角色的校验规则
                editRolesRules:{
                    // 角色名称校验规则
                    roleName: [
                        { required: true, message: '请输入角色名称', trigger: 'blur' },
                        { min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' }
                    ],
                    // 角色描述校验规则
                    roleDesc:[
                        { required: false, message: '请输入角色描述', trigger: 'blur' }
                    ]
                },
                // 正在编辑的角色id
                editRoleId:""
            }
        },
        // 生命周期函数
        created(){
            this.getRolesList()
        },
        // 方法
        methods:{
            // 获取角色列表数据
            async getRolesList(){
                // 向服务器发起数据请求
                const {data:res} = await this.$http.get("roles")
                // 将获取的数据保存
                this.rolesList = res.data
                // console.log(this.rolesList);
                
            },
            // 点击tag删除按钮，对Tag进行删除
            async deleteTag(role,rightId){
                const confirmTag = await this.$confirm('是否要删除角色权限', '删除权限', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).catch(
                    err=>err        
                );
                // console.log(confirmTag);
                // 如果点击的不是确定
                if(confirmTag !== "confirm"){
                    return this.$message.info("取消了删除操作")
                }
                // 点击的是确定按钮
                const {data:res} = await this.$http.delete(`roles/${role.id}/rights/${rightId}`)
                // 判断返回来的状态码
                if(res.meta.status !== 200){
                    return this.$message.error("删除权限失败")
                }
                // 删除成功，显示提示
                this.$message.success("删除权限成功")
                // 更新部分数据，重新渲染
                role.children = res.data          
            },
            // 点击权限分配按钮时，进行弹出框提示
            async editRight(role){
                // 当前要编辑的角色id 
                this.roleId = role.id
                // 将需要编辑的数据进行获取
                const {data:res} = await this.$http.get("rights/tree")
               
               
                // 判服务器返回的状态码
                if(res.meta.status !== 200){
                    return this.$message.error("获取权限数据失败")
                }
                // 将数据赋值给权限列表
                this.rightList = res.data
                // 调用递归进行保存选择的权限
                this.getRightId(role,this.rightYesList)
                
                this.editDialogClosed = true
            },
            // 递归保存权限列表的id值
            getRightId(node,arr){
                // 判断当前节点是否包含children数组
                if(!node.children){
                    // 当前节点不包含children数组
                    return arr.push(node.id)
                }
                // 当前节点包含children数组 进行遍历
                node.children.forEach(item=>{
                    // 进行递归调用
                    this.getRightId(item,arr)
                })

            },
            // 当点击权限分配弹出框的取消、确认按钮时要对所选的权限进行清空
            clearRight(){
                this.rightYesList = []       
            },
            //当点击权限对话框的确定按钮时，将数据进行提交
            async updateRights(){

                // 获取被选择的节点和子节点的id值
                const keys = [
                    ...this.$refs.treeRef.getCheckedKeys(),
                    ...this.$refs.treeRef.getHalfCheckedKeys()
                ]
              
                
                //以 `,` 分割的权限 ID 列表
                const idStr = keys.join(",")

                // 向服务器提交更新数据请求
                const {data:res} = await this.$http.post(`roles/${this.roleId}/rights`,{
                    rids:idStr
                })
         
                // 判断服务器提交的状态
                if(res.meta.status !== 200){
                    return this.$message.error("权限更新失败")
                }

                this.$message.success("权限更新成功")
                this.getRolesList()
                // 关闭对话框
                this.editDialogClosed = false
            },
            // 点击添加角色按钮，显示提示框
            showAddRoles(){
                this.addRolesVisible = true
            },
            // 点击角色添加提示框的取消按钮，进行表单清空
            resetAddRolesFrom(){
                this.$refs.addRolesRef.resetFields();
                this.addRolesVisible = false
            },
            // 点击角色添加提示框的提交按钮，进行表单提交
            async submitAddRolesFrom(){
              
                
                // 向服务器发起请求
                const {data:res} = await this.$http.post("roles",{
                    roleName:this.addRolesForm.roleName,
                    roleDesc:this.addRolesForm.roleDesc
                })

                // 对服务器状态码进行验证
                if(res.meta.status!==201){
                    return this.$message.error("添加角色失败")
                }
                
                this.$message.success("添加角色成功")
                // 对表单进行清空
                this.$refs.addRolesRef.resetFields();
                // 将提示框进行关闭
                this.addRolesVisible = false
                // 对页面数据进行更新
                this.getRolesList()
            },
            // 点击编辑角色按钮，显示提示框
            async showEditRoles(role){
                this.editRoleId = role.id
                console.log(role);
                
                //向服务器发起请求获取角色数据
                const {data:res} = await this.$http.get("roles/" + this.editRoleId)
                // 判断返回的状态码
                if(res.meta.status !== 200){
                    return this.$message.error("获取角色数据失败")
                }
                
                // 将获取的数据赋值给列表
                this.editRolesForm = res.data

                // 将提示框设置为显示
                this.editRolesVisible = true
            },
             // 点击角色添加提示框的取消按钮，进行表单清空
            resetEditRolesFrom(){
                this.$refs.editRolesRef.resetFields();
                this.editRolesVisible = false
            },
            // 当点击编辑提示框的确认按钮时，将表单进行提交
            async submitEditRolesFrom(){
                
                // 向服务器发起请求，将表单数据进行提交
                const {data:res} = await this.$http.put(`roles/${this.editRoleId}`,{
                    roleName:this.editRolesForm.roleName,
                    roleDesc:this.editRolesForm.roleDesc
                })

                if(res.meta.status !== 200){
                    return this.$message.error("更新角色失败")
                }

                this.$message.success("更新角色成功")

                this.$refs.editRolesRef.resetFields();
                this.editRolesVisible = false
                this.getRolesList()
            },
            // 点击删除角色按钮，弹出提示
            async  deleteRoles(role) {
                console.log(role);
                
                // 根据用户点击弹窗提示进行选择
                const confirmResult = await  this.$confirm('是否要删除此角色', '删除角色', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).catch(
                    err=>err
                );

                // 如果用户点击的取消按钮
                if(confirmResult !== "confirm"){
                    return this.$message.info("取消了删除操作")
                }

                // 如果用户点击的确定按钮,向服务器发起删除请求
                const {data:res} = await this.$http.delete("roles/" + role.id)
                // 判断返回来的状态码
                if(res.meta.status !== 200){
                    return this.$message.error("删除角色失败")
                }
                // 删除角色成功
                this.$message.success("删除角色成功")
                // 更新数据
                this.getRolesList()

            }

            
        }
    }
</script>

<style lang="less" scoped>
    .el-tag{
        margin: 15px 15px 15px 0;
       
    }

    .topBorder{
        border-top: 1px solid #eee ;
    }

    .bottomBorder{
        border-bottom: 1px solid #eee;
    }
    
    .vcenter{
        display: flex;
        align-items: center;
    }
    
</style>    